/*		Filename: 	card_manager.cpp
 *		Author:		彭望
 *		Date:		2012-01-11
 *		Use:		具体实现卡管理器对象
 */
#include "card_manager.h"


CCardManager::CCardManager(const DBManagerPtr& dbPtr)
		:m_dbPtr( dbPtr ), logger( Logger::getLogger() )
{
		logger.debug("Constructing CCardManager!");
}

RetCode_t CCardManager::add_card(const CCardInfo& info) const
{
	logger.debug("add card, card id : %s", info.get_cardId().c_str());
	RetCode_t ret = check_card(info);
	if( RET_OK != ret )
	{
			return ret;
	}
	return m_dbPtr->add_card(info);
}

RetCode_t CCardManager::delete_card(const CCardInfo& info) const 
{
	logger.debug("delete card, card id : %s", info.get_cardId().c_str());
	RetCode_t ret = check_card(info);
	CCardInfo tmp(info);
	//懒惰删除
	tmp.set_status(CCardInfo::STATUS_CANCELED);
	if( RET_OK != ret )
	{
			return ret;
	}
	//return m_dbPtr->delete_card(info);
	return m_dbPtr->update_card(tmp);
}

RetCode_t CCardManager::search_card(CCardInfo& info) const
{
	logger.debug("search card, card id : %s", info.get_cardId().c_str());
	RetCode_t ret = m_dbPtr->search_card(info);
	if( RET_OK != ret )
	{
			return ret;
	}
	return check_card(info);
}
RetCode_t CCardManager::update_card(const CCardInfo& info) const
{
	logger.debug("update card, card id : %s", info.get_cardId().c_str());
	RetCode_t ret = check_card(info);
	if( RET_OK != ret )
	{
			return ret;
	}
	return m_dbPtr->update_card(info);
}

RetCode_t CCardManager::check_card(const CCardInfo& info) const
{
	if( !CCardManager::isDigits( info.get_id() ) ){
			logger.warn("%s is not digit!", info.get_id().c_str());
			goto err;
	}
	else if( !CCardManager::isDigits(info.get_cardId()) )
	{
			logger.warn("%s is not digit!", info.get_cardId().c_str());
			goto err;
	}else if( !CCardManager::hasInvalidCharactor(info.get_password()) )
	{
			logger.warn("%s has invalid charactor!", info.get_password().c_str());
			goto err;
	}
	return RET_OK;
err:
	Logger::getLogger().warn("Card info invalid");
	return RET_INVALID_ARG;
}

bool CCardManager::isDigits(const string& value)
{
		try{
				boost::lexical_cast<double>(value);
		}catch(...)
		{
				return false;
		}
		return true;
}
bool CCardManager::hasInvalidCharactor(const string& value)
{
		for(size_t pos = 0; pos != value.length(); ++pos)
		{
				char c = value[pos];
				if( (c <= '9' && c >= '0') || ( c <= 'z' && c >= 'a' ) || ( c <= 'Z' && c >= 'A' ) )
				{
						continue;
				}else{
						return false;
				}
		}
		return true;
}
